<?php
/**
 * +--------------------------------------------------------------
 * | eLuoPHP
 * +--------------------------------------------------------------
 * | Copyright (c) 2016-2019 http://qxwoo.cn All rights reserved.
 * +--------------------------------------------------------------
 * | y139w [y139w@163.com]
 * +--------------------------------------------------------------
 * | 2019/6/24 14:17
 * +--------------------------------------------------------------
 * | Identity.php
 * +--------------------------------------------------------------
 */

namespace luo\traits;


trait Identity
{

    /**
     * 参与计算系数
     * @var array
     */
    private static $coefficient = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];

    /**
     * 最后一位检验码对应值
     * @var array
     */
    private static $corresponding = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];

    /**
     * 行政区划代码
     * @var array
     */
    private static $district = [];

    /**
     * 出生年月日
     * @var array
     */
    private static $birthday = [];

    /**
     * 前面17位
     * @var array
     */
    private static $seventeen = [];

    /**
     * 顺序码
     * @var array
     */
    private static $sequence = [];

    /**
     * 检验码
     * @var string
     */
    private static $check = null;

    /**
     * 处理身份证号
     * @param $identity
     * @return array
     */
    private static function discern($identity){

        self::$district = str_split(substr($identity, 0, 6));
        self::$birthday = str_split(substr($identity, 6, 8));
        self::$sequence = str_split(substr($identity, 14, 3));
        self::$check = substr($identity, 17, 1);
        self::$seventeen = str_split(substr($identity, 0, 17));
        return [
            'identity' => $identity,
            'district' => self::$district,
            'birthday' => self::$birthday,
            'sequence' => self::$sequence,
            'check' => self::$check,
            'seventeen' => self::$seventeen
        ];

    }

    /**
     * @param $identity
     * @return array
     */
    public static function testing($identity){

        return [
            'test' => self::test($identity),
            'birthday' => self::birth($identity),
            'gender' => self::gender($identity),
            'age' => self::age($identity)
        ];

    }

    /**
     * 验证身份证
     * @param $identity
     * @return bool
     */
    public static function test($identity){

        self::discern($identity);
        // 获取前17位
        $seventeen = self::$seventeen;

        // 乘积和
        $sum = 0;
        foreach(self::$coefficient as $key=>$val){
            $sum += $val * $seventeen[$key];
        }
        // 余数
        $remainder = $sum % 11;
        // 对应值
        $corresponding = strtolower(self::$corresponding[$remainder]);
        $check = strtolower(self::$check);
        return ($corresponding === $check);

    }

    /**
     * 获取出生日期
     * @param $identity
     * @param null $separator
     * @return array|bool|string
     */
    public static function birth($identity, $separator = null){

        self::discern($identity);

        // 获取出生日期数组
        $birthday = implode('', self::$birthday);

        $yearMonthDay = false;
        if(strlen($birthday) == 8){
            // 获取年份
            $year = substr($birthday, 0, 4);
            // 获取月份
            $month = substr($birthday, 4, 2);
            // 获取几日
            $day = substr($birthday, 6, 2);
            $yearMonthDay = [$year, $month, $day];
            if($separator){
                $yearMonthDay = implode($separator, $yearMonthDay);
            }
        }

        return $yearMonthDay;

    }

    /**
     * 获取性别
     * @param $identity
     * @return int
     */
    public static function gender($identity){

        self::discern($identity);

        $sequence = (int)implode('', self::$sequence);
        if($sequence % 2 === 0){
            $sex = 2;
        }else{
            $sex = 1;
        }
        return $sex;

    }

    /**
     * 获取年龄
     * @param $identity
     * @return int
     */
    public static function age($identity){

        self::discern($identity);
        $birth = self::birth($identity);
        $year = $birth[0] ?? 0;

        if($year >= date('Y')){
            $age = 0;
        }else{
            $age = (int)date('Y') - (int)$year;
        }
        return $age;

    }

}